#include "udpServer.hpp"
#include <memory>
using namespace Server;
#include <unordered_map>
#include <fstream>
#include <signal.h>
#include <stdio.h>
#include "UserMassage.hpp"

void my_Errno(char *n)
{
    printf("请正确输入#%s,port\n", n);
}

// const string dictTxt = "./dict.txt";
// unordered_map<string, string> dict; // 定义一个字典

// static bool cutString(string line, string *s1, string *s2, const string &sep)
// {
//     // apple:苹果
//     auto pos = line.find(sep);
//     if (pos == line.npos)
//     {
//         return false;
//     }
//     *s1 = line.substr(0, pos);
//     *s2 = line.substr(pos + sep.size()); // 这里相当于从：一直切到最后
//     return true;
// }

// static void initDict()
// {
//     // 以只读的方法打开文件
//     ifstream in(dictTxt, ios::binary);
//     // 打开失败就提示并且退出
//     if (!in.is_open())
//     {
//         cerr << "open file " << dictTxt << "errno" << endl;
//         exit(1);
//     }
//     // 到这里就是打开成功
//     string line; // 按行读取到line中
//     string key, value;
//     while (getline(in, line))
//     {
//         // cout << line << endl;

//         // 写一个输出型参数函数，把读取的数据切出来放到key和value中
//         if (cutString(line, &key, &value, ":"))
//         {
//             dict.insert(make_pair(key, value)); // 读取出来放到字典中
//         }
//     }
//     in.close();
//     cout << "load dict success" << endl;
// }

// 测试
// static void debugPrint()
// {
//     for (auto &e : dict)
//     {
//         cout << e.first << " # " << e.second << endl;
//     }
// }

// demo1:字典翻译：客户端输入单词，服务端翻译后返回给客户端
// void handlerMessage(int sockfd, string clientip, uint16_t clientport, string message)
// {
//     // 在这里就可以对message进行特定的业务处理，而不关系message是怎么来的---server通信与业务逻辑的解耦
//     // 婴儿版的业务逻辑
//     string respose_message;
//     auto iter = dict.find(message);
//     if (iter == dict.end())
//     {
//         respose_message = "unknown";
//     }
//     else
//     {
//         respose_message = iter->second;
//     }

//     // 开始返回
//     struct sockaddr_in client;
//     client.sin_family = AF_INET;
//     client.sin_port = htons(clientport);
//     client.sin_addr.s_addr = inet_addr(clientip.c_str());

//     // 将客户端发送的数据里面的value值返回
//     sendto(sockfd, respose_message.c_str(), sizeof(respose_message), 0, (sockaddr *)&client, sizeof(client));
// }

// demo2:客户端向服务端发送shell命令，服务器接收后，把结果返回给客户端
// void execCommand(int sockfd, string clientip, uint16_t clientport, string cmd)
// {

//     if (cmd.find("rm") != string::npos || cmd.find("mv") != string::npos || cmd.find("rmdir") != string::npos)
//     {
//         cerr << clientip << ":" << clientport << "正在进行非法操作" << cmd << endl;
//         return;
//     }

//     string respose_message;
//     FILE *fp = popen(cmd.c_str(), "r");
//     if (fp == nullptr)
//         respose_message = cmd + "exec failed";

//     char line[1024];
//     while (fgets(line, sizeof(line), fp))
//     {
//         respose_message += line;
//     }
//     pclose(fp);

//     // 开始返回
//     struct sockaddr_in client;
//     bzero(&client, sizeof(client));

//     client.sin_family = AF_INET;
//     client.sin_port = htons(clientport);
//     client.sin_addr.s_addr = inet_addr(clientip.c_str());

//     sendto(sockfd, respose_message.c_str(), sizeof(respose_message), 0, (sockaddr *)&client, sizeof(client));
// }

OnlineUser onlineuser;
// demo3:做一个用户登录的管理
void routeMessage(int sockfd, string clientip, uint16_t clientport, string message)
{
    if (message == "online")
    {
        onlineuser.addUser(clientip, clientport);
    }
    if (message == "offline")
    {
        onlineuser.delUser(clientip, clientport);
    }
    if (onlineuser.isOnline(clientip, clientport))
    {
        // 在线:让所有在线的用户都可以看到聊天室的信息
        onlineuser.broadcastMessage(sockfd, clientip, clientport, message);
    }
    else
    {
        // 不在线
        struct sockaddr_in client;
        bzero(&client,sizeof(client));

        client.sin_family = AF_INET;
        client.sin_port = htons(clientport);
        client.sin_addr.s_addr = inet_addr(clientip.c_str());

        string response = "你还没有上线,请先上线,运行:online";
        sendto(sockfd, response.c_str(), response.size(), 0, (sockaddr *)&client, sizeof(client));
    }
}

// void reload(int signo)
// {
//     (void)signo;
//     // 热加载
//     initDict(); // 输入这个信号刷新字典的内容
// }
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        my_Errno(argv[0]);
        exit(1);
    }

    // string ip = argv[1];
    uint16_t port = atoi(argv[1]);

    // 捕捉3号信号
    // signal(2, reload);

    // initDict();
    //  debugPrint();测试成功

    // unique_ptr<udpServer> ret(new udpServer(handlerMessage, port));
    // unique_ptr<udpServer> ret(new udpServer(execCommand, port));

        unique_ptr<udpServer> ret(new udpServer(routeMessage, port));

    ret->initServer();
    ret->start();

    return 0;
}
